package dse.messages.singleversion;

import java.util.*;

import dse.DataObject;
import dse.DataShare;
import dse.Experiment;
import dse.ExperimentRecorder;
import dse.Node;
import dse.Version;
import dse.messages.Message;
import dse.messages.MessageHandler;
import dse.messages.MessageSender;
import dse.messages.MessageType;

public class SendMACHenMessageHandler extends MessageSender implements
		MessageHandler {
	private DataObject dobj;
	private Version version;
	private ShareDownloader downloader;
	
	public SendMACHenMessageHandler(Experiment exp, DataObject dobj, Version v, ShareDownloader downloader){
		super(exp);
		this.dobj = dobj;
		this.version = v;
		this.downloader = downloader;
	}
	@Override
	public boolean acceptMessage(Message message) {
		// TODO Auto-generated method stub
		return true;
	}

	@Override
	public void messageInterupted(ExperimentRecorder recorder, Message message,
			double time) {
		// TODO Auto-generated method stub
		if(ExperimentRecorder.debug)
			recorder.debug(this, "msgIntrpt: " + message, time);
		downloader.shareUpdateFailed(recorder, dobj, 0, time);
	}

	@Override
	public void messageReceived(ExperimentRecorder recorder, Message message,
			double time) {
		// TODO Auto-generated method stub
		if(ExperimentRecorder.debug)
			recorder.debug(this, "msgRcvd: " + message, time);
		if (message.messageType() != MessageType.SendMACHen) {
			recorder.warn(
					"SendMACHenMessageHandler recieved " + 
					message.messageType() + " message."
					);
			return;
		}			
		// What do we know about the share?
		Node receiver = message.to();
		
		// Does the receiver have the share?
		DataShare share = receiver.getDataShare(dobj);
		if (share != null)
		{
			// Then we need to send a new message BACK (thats why to and from
			// are reversed!
			if(version.compareTo(share.getLatest()) > 0){
				share.updateVersion(version);
				TreeMap<Version, LinkedList<Node>> volatileShares = share.getVolatileVersions();
				if(volatileShares != null){
					while(volatileShares.size()>0 && volatileShares.firstKey().compareTo(version) <= 0){
						volatileShares.pollFirstEntry();
					}
				}
			}
			else{
				share.removeVolatileVersion(version);
			}			
			downloader.shareUpdated(recorder, message.from(), dobj, share.getIndex(), time);
		}
		else
		{
			this.messageInterupted(recorder, message, time);
		}
	}

}
